#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL fa[maxn];
LL find(LL x){
    if(x!=fa[x]) return fa[x]=find(fa[x]);
    return fa[x];
}
struct Edge{
    LL u,v,val;
}edges[maxn];
bool cmp(Edge A,Edge B){
    return A.val<B.val;
}
map<string,LL>map1;
int main(void)
{
  ///cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,m;
  while(cin>>n>>m){
    map1.clear();
    for(LL i=1;i<=n;i++) fa[i]=i;
    for(LL i=1;i<=m;i++) edges[i].u=edges[i].v=edges[i].val=0;
    string tmp;cin>>tmp;
    LL tot=0;
    for(LL i=1;i<=m;i++){
        string a,b;cin>>a>>b;
        LL u,v;
        if(map1.count(a)) u=map1[a];
        else{
            map1[a]=++tot;
            u=map1[a];
        }
        if(map1.count(b)) v=map1[b];
        else{
            map1[b]=++tot;
            v=map1[b];
        }
        cin>>edges[i].val;
        edges[i].u=u;edges[i].v=v;
    }
    sort(edges+1,edges+1+m,cmp);
    LL ans=0;
    for(LL i=1;i<=m;i++){
        LL u=find(edges[i].u);LL v=find(edges[i].v);
        if(u==v) continue;
        ans+=edges[i].val;
        fa[find(u)]=v;
    }
    LL sum=0;
    for(LL i=1;i<=n;i++){
        if(fa[i]==i) sum++;
    }
    if(sum>=2){
        cout<<"No!"<<"\n";
    }
    else cout<<ans<<"\n";
  }
return 0;
}
